import { defineStore } from "pinia";
import {
  type userType,
  store,
  router,
  resetRouter,
  routerArrays,
  storageLocal
} from "../utils";
import {
  type UserResult,
  type RefreshTokenResult,
  getLogin,
  getInfo,
  logout,
  refreshTokenApi
} from "@/api/user";
import { useMultiTagsStoreHook } from "./multiTags";
import { type DataInfo, setToken, removeToken, userKey } from "@/utils/auth";
import {
  setToken as setRuoyiToken,
  getToken as getRuoyiToken,
  removeToken as removeRuoyiToken
} from "@/utils/ruoyiAuth"; //Todo: pureadmin token结构不同
import { ElMessageBox } from "element-plus";
import { isHttp, isEmpty } from "@/utils/validate";
import defAva from "@/assets/images/profile.jpg";

export const useUserStore = defineStore("pure-user", {
  state: (): userType => ({
    uid: storageLocal().getItem<DataInfo<number>>(userKey)?.uid ?? "",
    // 头像
    avatar: storageLocal().getItem<DataInfo<number>>(userKey)?.avatar ?? "",
    // 用户名
    username: storageLocal().getItem<DataInfo<number>>(userKey)?.username ?? "",
    // 昵称
    nickname: storageLocal().getItem<DataInfo<number>>(userKey)?.nickname ?? "",
    // 页面级别权限
    // roles: storageLocal().getItem<DataInfo<number>>(userKey)?.roles ?? [],
    roles: [], //页面级别权限不读取缓存
    // 按钮级别权限
    permissions: [], //权限不读取缓存
    // storageLocal().getItem<DataInfo<number>>(userKey)?.permissions ?? [],
    // 是否勾选了登录页的免登录
    isRemembered: false,
    // 登录页的免登录存储几天，默认7天
    loginDay: 7
  }),
  actions: {
    /** 存储用户ID */
    SET_UID(uid: string) {
      this.uid = uid;
    },
    /** 存储头像 */
    SET_AVATAR(avatar: string) {
      this.avatar = avatar;
    },
    /** 存储用户名 */
    SET_USERNAME(username: string) {
      this.username = username;
    },
    /** 存储昵称 */
    SET_NICKNAME(nickname: string) {
      this.nickname = nickname;
    },
    /** 存储角色 */
    SET_ROLES(roles: Array<string>) {
      this.roles = roles;
    },
    /** 存储按钮级别权限 */
    SET_PERMS(permissions: Array<string>) {
      this.permissions = permissions;
    },
    /** 存储是否勾选了登录页的免登录 */
    SET_ISREMEMBERED(bool: boolean) {
      this.isRemembered = bool;
    },
    /** 设置登录页的免登录存储几天 */
    SET_LOGINDAY(value: number) {
      this.loginDay = Number(value);
    },
    /** 登入 */
    async loginByUsername(data) {
      return new Promise<UserResult>((resolve, reject) => {
        getLogin(data)
          .then(data => {
            if (data?.success) {
              //首先写入ruoyi token
              setRuoyiToken(data.token);
              resolve(data);
            } else {
              reject("登录失败");
            }
          })
          .then(() => {
            this.getInfo();
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    // 获取用户信息
    async getInfo() {
      return new Promise((resolve, reject) => {
        getInfo()
          .then(res => {
            const user = res.user;
            let avatar = user.avatar || "";
            if (!isHttp(avatar)) {
              avatar = isEmpty(avatar)
                ? defAva
                : import.meta.env.VITE_APP_BASE_API + avatar;
            }
            let roles,
              permissions = [];
            if (res.roles && res.roles.length > 0) {
              // 验证返回的roles是否是一个非空数组
              roles = res.roles;
              permissions = res.permissions;
            } else {
              roles = ["ROLE_DEFAULT"];
            }

            // 存储用户信息到本地存储
            const info: DataInfo<Date> = {
              accessToken: getRuoyiToken(),
              refreshToken: getRuoyiToken(),
              expires: new Date(Date.now() + 30 * 60 * 1000), //ruoyi-backend 不返回 expires 字段
              uid: user.userId,
              username: user.userName,
              nickname: user.nickName,
              avatar: avatar,
              roles: roles,
              permissions: permissions
            };
            // 存储用户信息到pinia
            this.SET_UID(info.uid);
            this.SET_AVATAR(info.avatar);
            this.SET_USERNAME(info.username);
            this.SET_NICKNAME(info.nickname);
            this.SET_ROLES(info.roles);
            this.SET_PERMS(info.permissions);
            setToken(info);
            /* 初始密码提示 */
            if (res.isDefaultModifyPwd) {
              ElMessageBox.confirm(
                "您的密码还是初始密码，请修改密码！",
                "安全提示",
                {
                  confirmButtonText: "确定",
                  cancelButtonText: "取消",
                  type: "warning"
                }
              )
                .then(() => {
                  router.push({
                    name: "Profile",
                    params: { activeTab: "resetPwd" }
                  });
                })
                .catch(() => {});
            }
            /* 过期密码提示 */
            if (!res.isDefaultModifyPwd && res.isPasswordExpired) {
              ElMessageBox.confirm(
                "您的密码已过期，请尽快修改密码！",
                "安全提示",
                {
                  confirmButtonText: "确定",
                  cancelButtonText: "取消",
                  type: "warning"
                }
              )
                .then(() => {
                  router.push({
                    name: "Profile",
                    params: { activeTab: "resetPwd" }
                  });
                })
                .catch(() => {});
            }
            resolve(res);
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    /** 前端登出（不调用接口） */
    logOut() {
      return new Promise((resolve, reject) => {
        logout()
          .then(() => {
            this.username = "";
            this.roles = [];
            this.permissions = [];
            removeToken();
            removeRuoyiToken();
            useMultiTagsStoreHook().handleTags("equal", [...routerArrays]);
            resetRouter();
            router.push("/login");
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    /** 刷新`token` */
    async handRefreshToken(data) {
      return new Promise<RefreshTokenResult>((resolve, reject) => {
        refreshTokenApi(data)
          .then(data => {
            if (data) {
              setToken({
                accessToken: data.data.accessToken,
                refreshToken: data.data.refreshToken,
                expires: data.data.expires
              });
              resolve(data);
            }
          })
          .catch(error => {
            reject(error);
          });
      });
    }
  }
});

export function useUserStoreHook() {
  return useUserStore(store);
}

export default useUserStoreHook;
